namespace ASPNET.StarterKit.IssueTracker.BusinessLogicLayer
{
    using System;
    using System.Collections;
    using System.Reflection;

    public class ProjectCollection : CollectionBase
    {
        public int Add(Project value)
        {
            return this.List.Add(value);
        }

        public bool Contains(Project value)
        {
            return this.List.Contains(value);
        }

        public int IndexOf(Project value)
        {
            return this.List.IndexOf(value);
        }

        public void Insert(int index, Project value)
        {
            this.List.Insert(index, value);
        }

        protected override void OnInsert(int index, object value)
        {
            if (value.GetType() != Type.GetType("ASPNET.StarterKit.IssueTracker.BusinessLogicLayer.Project"))
            {
                throw new ArgumentException("value must be of type Project.", "value");
            }
        }

        protected override void OnRemove(int index, object value)
        {
            if (value.GetType() != Type.GetType("ASPNET.StarterKit.IssueTracker.BusinessLogicLayer.Project"))
            {
                throw new ArgumentException("value must be of type Project.", "value");
            }
        }

        protected override void OnSet(int index, object oldValue, object newValue)
        {
            if (newValue.GetType() != Type.GetType("ASPNET.StarterKit.IssueTracker.BusinessLogicLayer.Project"))
            {
                throw new ArgumentException("newValue must be of type Project.", "newValue");
            }
        }

        protected override void OnValidate(object value)
        {
            if (value.GetType() != Type.GetType("ASPNET.StarterKit.IssueTracker.BusinessLogicLayer.Project"))
            {
                throw new ArgumentException("value must be of type Project.");
            }
        }

        public void Remove(Project value)
        {
            this.List.Remove(value);
        }

        public void Sort(ProjectFields sortField, bool isAscending)
        {
            switch (sortField)
            {
                case ProjectFields.Name:
                    this.InnerList.Sort(new NameComparer());
                    break;

                case ProjectFields.Creator:
                    this.InnerList.Sort(new CreatorComparer());
                    break;

                case ProjectFields.Manager:
                    this.InnerList.Sort(new ManagerComparer());
                    break;

                case ProjectFields.DateCreated:
                    this.InnerList.Sort(new CreatedComparer());
                    break;
            }
            if (!isAscending)
            {
                this.InnerList.Reverse();
            }
        }

        public Project this[int index]
        {
            get
            {
                return (Project) this.List[index];
            }
            set
            {
                this.List[index] = value;
            }
        }

        private sealed class CreatedComparer : IComparer
        {
            public int Compare(object x, object y)
            {
                Issue first = (Issue) x;
                Issue second = (Issue) y;
                return first.DateCreated.CompareTo(second.DateCreated);
            }
        }

        private sealed class CreatorComparer : IComparer
        {
            public int Compare(object x, object y)
            {
                Project first = (Project) x;
                Project second = (Project) y;
                return first.CreatorDisplayName.CompareTo(second.CreatorDisplayName);
            }
        }

        private sealed class ManagerComparer : IComparer
        {
            public int Compare(object x, object y)
            {
                Project first = (Project) x;
                Project second = (Project) y;
                return first.ManagerDisplayName.CompareTo(second.ManagerDisplayName);
            }
        }

        private sealed class NameComparer : IComparer
        {
            public int Compare(object x, object y)
            {
                Project first = (Project) x;
                Project second = (Project) y;
                return first.Name.CompareTo(second.Name);
            }
        }

        public enum ProjectFields
        {
            InitValue,
            Name,
            Creator,
            Manager,
            DateCreated
        }
    }
}

